package com.wiz.web.manager;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.wiz.common.TencentConfigure;

/**
 * ssl协议管理器
 * @author Hakeny
 */
@Service("httpSSLManager")
public class HttpSSLManager {
	private transient final Logger log = LoggerFactory.getLogger(getClass());

	private CloseableHttpClient cc;
	private RequestConfig requestConfig = RequestConfig.custom()
			.setSocketTimeout(30000).setConnectTimeout(30000).build();
	
	/**
	 * 获得http链接工厂
	 * @return
	 * @throws Exception 
	 */
	private synchronized CloseableHttpClient getClient() throws Exception {
		if (cc == null) {
			cc = getCloseableHttpClient();
		}
		return cc;
	}
	
	/**
	 * 微信要求格式请求
	 * @param url
	 * @param xmlObj
	 * @return
	 */
	public String sendWxPost(String url, Object xmlObj) {
		String result = "fail";
		HttpPost httpPost = new HttpPost(url);
		// 解决XStream对出现双下划线的bug
		XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8",
				new XmlFriendlyNameCoder("-_", "_")));
		// 将要提交给API的数据对象转换成XML格式数据Post给API
		String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
		System.out.println("httpSSL="+postDataXML);
		// 得指明使用UTF-8编码，否则到API服务器XML的中文不能被成功识别
		StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
		httpPost.addHeader("Content-Type", "text/xml");
		httpPost.setEntity(postEntity);
		httpPost.setConfig(requestConfig);
		try {
			CloseableHttpClient httpClient = getClient();
			CloseableHttpResponse response = httpClient.execute(httpPost);
			try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
                    String text;
                    StringBuffer sb = new StringBuffer();
                    while ((text = bufferedReader.readLine()) != null) {
                        sb.append(text);
                    }
                    result = sb.toString();
                }
                EntityUtils.consume(entity);
                
            } finally {
                response.close();
            }
		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			httpPost.abort();
		}
		return result;
	}
	
	private CloseableHttpClient  getCloseableHttpClient() throws Exception{
		KeyStore keyStore = KeyStore.getInstance("PKCS12");
		FileInputStream instream = new FileInputStream(new File(
				"/usr/local/wiz_log/apiclient_cert.p12"));
		try {
			keyStore.load(instream, TencentConfigure.getMchid().toCharArray());
		} finally {
			instream.close();
		}
		// Trust own CA and all self-signed certs
		SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, TencentConfigure.getMchid().toCharArray()).build();
		// Allow TLSv1 protocol only
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
				sslcontext, new String[] { "TLSv1" }, null,
				SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		return HttpClients.custom().setSSLSocketFactory(sslsf).build();
	}
}
